﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core.Property;

namespace Cofe.Core.Filter
{
    public class FilterCollections
    {
        public IEntryFilter[] EntryFilters { get; private set; }
        public IOptionFilter[] OptionFilters { get; private set; }
        public IFilter[] AllFilters { get; private set; }

        public FilterCollections()
        {
            EntryFilters = new IEntryFilter[] { };
            OptionFilters = new IOptionFilter[] { };
            AllFilters = new IFilter[] { };
        }

        public static FilterCollections FromFilters(IEntryFilter[] entryFilters, IOptionFilter[] optionFilters)
        {
            List<IFilter> allFilters = new List<IFilter>();
            allFilters.AddRange(entryFilters);
            allFilters.AddRange(optionFilters);

            if (!(entryFilters.Any(ef => ef is IRootEntryFilter)) &&
                optionFilters.Any(of => of is ISearchOptionOptionFilter))
                allFilters.Add(new RootEntryFilter(""));

            return new FilterCollections() { EntryFilters = entryFilters, OptionFilters = optionFilters, AllFilters = allFilters.ToArray() };
        }

        public static FilterCollections FromFilters(params IFilter[] allfilters)
        {
            return new FilterCollections()
            {
                EntryFilters = allfilters.Where(f => f is IEntryFilter).Select(f => f as IEntryFilter).ToArray(),
                OptionFilters = allfilters.Where(f => f is IOptionFilter).Select(f => f as IOptionFilter).ToArray(),
                AllFilters = allfilters
            };
        }

        public static FilterCollections FromFilterString(string filterStr)
        {
            IEntryFilter[] entryFilters;
            IOptionFilter[] optionFilters;
            CofeServices.EntryFilterParser.ParseFilter(filterStr, out entryFilters, out optionFilters);
            return FromFilters(entryFilters, optionFilters);
        }

        public static FilterCollections FromParseName(string parseName)
        {
            return FromFilters(new ParseNameEntryFilter(parseName));
        }

        public static FilterCollections FromName(string name)
        {
            return FromFilters(new FileNameEntryFilter(name));
        }

        /// <summary>
        /// Apply to child entries that have the specified parent with the parseName.
        /// </summary>
        /// <param name="parseName"></param>
        /// <param name="searchOption"></param>
        /// <returns></returns>
        public static FilterCollections FromParentParseName(string parseName, SearchOption searchOption = SearchOption.TopDirectoryOnly)
        {
            if (searchOption != SearchOption.TopDirectoryOnly)
                return FromFilters(new RootEntryFilter(parseName), new SearchOptionOptionFilter(searchOption));
            else return FromFilters(new RootEntryFilter(parseName));
        }

        public static FilterCollections FromPropertyHost(IPropertyHost propertyHost)
        {
            string parseName = propertyHost.Behaviors.GetProperty<string>(CofeProperties.FullParseName);
            return FromParseName(parseName);
        }

        public static FilterCollections FromGuid(Guid id)
        {
            return FromFilters(new GuidEntryFilter(id));
        }

        /// <summary>
        /// Apply to child entries that have the specified parent with the parent id.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static FilterCollections FromParentGuid(Guid id)
        {
            return FromFilters(new ParentGuidEntryFilter(id));
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (var f in AllFilters)
                sb.Append(f.ToString() + Environment.NewLine);
            return sb.ToString();
        }
    }
}
